package com.bank.domain;


import java.sql.Date;
import java.sql.Timestamp;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;

import com.bank.annotation.Matches;

@Matches(fields={"password"}, verifyFields={"passwordRepeat"}, dates = { "birthDate" })
@Entity
@Table(name = "customers" )
public class Customer implements ConstraintValidator<Matches, Object> {

	private static final long serialVersionUID = -5527566248002296042L;
	
	private CustomerRole CustomerRole;
	
	@Id
	@Column(name = "CUSTOMER_ID")
	@GeneratedValue
	private Integer customerId;
	
	@Length(min=3, max=15)
	@Column(name = "NAME")
	private String name;
	
	@Length(min=3, max=15)
	@Column(name = "SURNAME")
	private String surname;

	@Email
	@NotNull
	@Column(name = "EMAIL")
	private String email;
	
	@Length(min=5, max=15)
	@Column(name = "PASSWORD")
	private String password;

	@Transient
	private String passwordRepeat;
	
	@Column(name = "CLIENT_NUMBER")
	private Integer clientNumber;
	
	@NotNull
	@Pattern(regexp="^[0-9]{11}$", message = "Wrong person code format")
	@Column(name = "PERSON_CODE")
	private String personCode;
	
	
	@Column(name = "ROLE_ID")
	private Integer roleId;
	
	@Column(name = "ACTIVE")
	private Integer active;
	
	@Column(name = "BLOCKED")
	private Integer blocked;
	
	@Column(name = "DATE_CREATED")
	private Date dateCreated;
	
	@Column(name = "DATE_MODIFIED")
	private Timestamp dateModified;
	
	@NotNull
	@Column(name = "BIRTH_DATE")
	private Date birthDate;
	
    @OneToMany(
            cascade=CascadeType.MERGE, fetch=FetchType.EAGER
        )

	@JoinTable(
            name="customeraccount",
            joinColumns = @JoinColumn( name="CUSTOMER_ID"),
            inverseJoinColumns = @JoinColumn( name="ACCOUNT_ID")
    )
    private Set<Account> Accounts;

    @OneToMany(
            cascade=CascadeType.MERGE, fetch=FetchType.EAGER
        )

	@JoinTable(
            name="customertransaction",
            joinColumns = @JoinColumn( name="CUSTOMER_ID"),
            inverseJoinColumns = @JoinColumn( name="TRANSACTION_ID")
    )
    private Set<Transaction> Transactions;

    @ManyToMany(
            cascade=CascadeType.MERGE, fetch=FetchType.EAGER
        )

	@JoinTable(
            name="customercodeslink",
            joinColumns = @JoinColumn( name="CUSTOMER_CODE_ID"),
            inverseJoinColumns = @JoinColumn( name="CUSTOMER_ID")
    )
    private Set<CustomerCode> Codes;
    

	@ManyToOne(cascade = CascadeType.ALL)
	public CustomerRole getCustomerRole() {
		return CustomerRole;
	}
	public void setCurrency(CustomerRole CustomerRole) {
		this.CustomerRole = CustomerRole;
	}


	/**
	 * @return the transactions
	 */
	public Set<Transaction> getTransactions() {
		return Transactions;
	}

	/**
	 * @param transactions the transactions to set
	 */
	public void setTransactions(Set<Transaction> transactions) {
		Transactions = transactions;
	}

	/**
	 * @return the customerId
	 */
	public Integer getCustomerId() {
		return customerId;
	}

	/**
	 * @param customerId the customerId to set
	 */
	public void setCustomerId(Integer customerId) {
		this.customerId = customerId;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}


	
	/**
	 * @return the passwordRepeat
	 */
	public String getPasswordRepeat() {
		return passwordRepeat;
	}
	/**
	 * @param passwordRepeat the passwordRepeat to set
	 */
	public void setPasswordRepeat(String passwordRepeat) {
		this.passwordRepeat = passwordRepeat;
	}
	/**
	 * @return the surname
	 */
	public String getSurname() {
		return surname;
	}

	/**
	 * @param surname the surname to set
	 */
	public void setSurname(String surname) {
		this.surname = surname;
	}

	/**
	 * @return the email
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * @param email the email to set
	 */
	public void setEmail(String email) {
		this.email = email;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the clientNumber
	 */
	public Integer getClientNumber() {
		return clientNumber;
	}

	/**
	 * @param clientNumber the clientNumber to set
	 */
	public void setClientNumber(Integer clientNumber) {
		this.clientNumber = clientNumber;
	}

	/**
	 * @return the personCode
	 */
	public String getPersonCode() {
		return personCode;
	}

	/**
	 * @param personCode the personCode to set
	 */
	public void setPersonCode(String personCode) {
		this.personCode = personCode;
	}

	/**
	 * @return the birthDate
	 */
	public Date getBirthDate() {
		return birthDate;
	}

	/**
	 * @param birthDate the birthDate to set
	 */
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}

	/**
	 * @return the roleId
	 */
	public Integer getRoleId() {
		return roleId;
	}

	/**
	 * @param roleId the roleId to set
	 */
	public void setRoleId(Integer roleId) {
		this.roleId = roleId;
	}

	/**
	 * @return the active
	 */
	public Integer getActive() {
		return active;
	}

	/**
	 * @param active the active to set
	 */
	public void setActive(Integer active) {
		this.active = active;
	}

	/**
	 * @return the blocked
	 */
	public Integer getBlocked() {
		return blocked;
	}

	/**
	 * @param blocked the blocked to set
	 */
	public void setBlocked(Integer blocked) {
		this.blocked = blocked;
	}

	/**
	 * @return the dateCreated
	 */
	public Date getDateCreated() {
		return dateCreated;
	}

	/**
	 * @param dateCreated the dateCreated to set
	 */
	public void setDateCreated(Date dateCreated) {
		this.dateCreated = dateCreated;
	}

	/**
	 * @return the dateModified
	 */
	public Timestamp getDateModified() {
		return dateModified;
	}

	/**
	 * @param dateModified the dateModified to set
	 */
	public void setDateModified(Timestamp dateModified) {
		this.dateModified = dateModified;
	}

	/**
	 * @return the accounts
	 */
	public Set<Account> getAccounts() {
		return Accounts;
	}

	/**
	 * @param accounts the accounts to set
	 */
	public void setAccounts(Set<Account> accounts) {
		Accounts = accounts;
	}

	/**
	 * @return the serialversionuid
	 */
	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	/**
	 * @return the codes
	 */
	public Set<CustomerCode> getCodes() {
		return Codes;
	}
	/**
	 * @param codes the codes to set
	 */
	public void setCodes(Set<CustomerCode> codes) {
		Codes = codes;
	}
	/**
	 * @param customerRole the customerRole to set
	 */
	public void setCustomerRole(CustomerRole customerRole) {
		CustomerRole = customerRole;
	}

	public boolean isValid(Object value, ConstraintValidatorContext context) {
		// TODO Auto-generated method stub
		return false;
	}
	public void initialize(Matches constraintAnnotation) {
		// TODO Auto-generated method stub
		
	}
	
    
    

	
	

}
